import { ref, onMounted, reactive, computed, watch } from "vue";
import { message } from "@/utils/message";

import { getCategoryDictionary } from "@/api/blog/category";
import { getTagDictionary } from "@/api/blog/tag";
import {
  addArticle,
  type ArticleForm,
  editArticle,
  titleExist
} from "@/api/blog/article";
import { ImgUpload } from "@/api/blog/site";
import { tagV, coverV } from "./validator";
import { ElLoading } from "element-plus";

export function useArticle(
  props: { visible: boolean; articleForm: ArticleForm; onSearch?: () => void },
  emit: (event: "update:visible", val: boolean) => void
) {
  const isVisible = computed({
    get: () => props.visible,
    set: (val: boolean) => emit("update:visible", val)
  });
  // 本地 form 状态副本
  const form = ref<ArticleForm>({ ...props.articleForm });
  // 记录原始标题
  const originalTitle = ref("");
  // 监听 props 变更，更新 form 副本
  watch(
    () => props.articleForm,
    newVal => {
      form.value = JSON.parse(JSON.stringify(newVal)); // 深拷贝
      originalTitle.value = newVal?.title || ""; // 记录初始标题
    },
    { immediate: true, deep: true }
  );
  const dialogVisible = ref(false);
  const articleFormRef = ref();
  const dialogArticleFormRef = ref();
  const canPublish = ref(true);

  const tagOptionList = ref([]);
  const categoryOptionList = ref([]);

  const coverPreviewVisible = ref(false);
  const coverUrl = ref(null);

  // 校验规则
  const articleFormRules = reactive({
    title: {
      required: true,
      trigger: "blur",
      message: "请输入文章标题"
    },
    content: {
      required: true,
      message: "请输入文章内容",
      trigger: "blur"
    }
  });
  // 校验规则
  const dialogArticleFormRules = reactive({
    author: { required: true, message: "请输入作者名称", trigger: ["blur"] },
    categoryId: {
      required: true,
      message: "请选择文章分类",
      trigger: ["change"]
    },
    summary: {
      required: true,
      message: "请输入文章摘要",
      trigger: ["blur"]
    },
    tags: {
      required: true,
      message: "请选择文章标签",
      validator: tagV,
      trigger: ["change"]
    },
    coverList: {
      required: true,
      message: "请上传文章封面",
      validator: coverV,
      trigger: ["change"]
    },
    origin_url: {
      required: true,
      message: "请输入原文链接",
      trigger: ["blur"]
    }
  });

  function closeDialog() {
    resetForm(dialogArticleFormRef.value);
    dialogVisible.value = false;
  }

  const resetForm = formEl => {
    if (!formEl) return;
    formEl.resetFields();
  };

  // 发布文章 打开弹窗
  async function publish(formEl) {
    if (!formEl) return;
    if (!canPublish.value) {
      message("文章标题重复，换个标题试试", { type: "warning" });
      return;
    }
    await formEl.validate(valid => {
      if (valid) {
        dialogVisible.value = true;
      } else {
        message("请按照提示填写信息", { type: "warning" });
      }
    });
  }
  // 图片上传
  async function uploadCover() {
    if (!form.value.coverList[0].id) {
      const upLoadLoading = ElLoading.service({
        fullscreen: true,
        text: "图片上传中"
      });
      const file: File = form.value.coverList[0].raw;
      const res = await ImgUpload(file);
      if (res) {
        const { url } = res;
        form.value.cover = url;
      }
      upLoadLoading.close();
    }
  }

  async function articleTitleVAlidate() {
    const { title } = form.value;
    // 如果标题未改动，跳过校验
    if (title === originalTitle.value) {
      canPublish.value = true;
      return;
    }
    const res = await titleExist({ title });
    if (res) {
      canPublish.value = false;
      message("文章标题已存在，换一个试试", { type: "warning" });
    } else {
      canPublish.value = true;
    }
  }

  // 上传md文章图片
  async function uploadImage(files, callback) {
    const res = await Promise.all(
      files.map(file => {
        return new Promise(resolve => {
          ImgUpload(file).then(imgData => {
            if (imgData) {
              const { url } = imgData;
              resolve(url);
            }
          });
        });
      })
    );

    callback(res);
  }

  // 整理文章的数据返回给后端
  function arrangeArticle(articleForm) {
    const { id, tags, ...restArticle } = articleForm.value;
    const newTagList = [];
    tags.forEach(tagId => {
      if (typeof tagId == "number") {
        newTagList.push(tagOptionList.value.find(tag => tag.id == tagId).name);
      } else {
        newTagList.push(tagId);
      }
    });
    restArticle.tags = newTagList;
    if (id) {
      restArticle.id = id;
    }
    return restArticle;
  }

  // 发布
  async function submitForm(formEl) {
    await formEl.validate(async valid => {
      if (valid) {
        // 图片上传
        await uploadCover();
        // 整合数据
        const finalArticle = arrangeArticle(form);
        let res;
        const loading = ElLoading.service({
          lock: true,
          text: "Loading",
          background: "rgba(0, 0, 0, 0.7)"
        });
        if (!finalArticle.id) {
          // 新增
          res = await addArticle(finalArticle);
        } else {
          // 编辑
          res = await editArticle(finalArticle.id, finalArticle);
        }
        if (res) {
          loading.close();
          resetForm(formEl.value);
          resetForm(articleFormRef.value);
          dialogVisible.value = false;
          // 关闭父组件窗口
          isVisible.value = false;
          props.onSearch?.();
        }
      } else {
        message("请按照提示填写信息", { type: "warning" });
      }
    });
  }

  // 获取标签列表
  async function getTagD() {
    const res = await getTagDictionary();
    if (res) {
      tagOptionList.value = res;
    }
  }
  // 获取分类列表
  async function getCategoryD() {
    const res = await getCategoryDictionary();
    if (res) {
      categoryOptionList.value = res;
    }
  }

  onMounted(async () => {
    await getTagD();
    await getCategoryD();
  });

  return {
    coverUrl,
    form,
    dialogVisible,
    tagOptionList,
    articleFormRef,
    articleFormRules,
    categoryOptionList,
    coverPreviewVisible,
    dialogArticleFormRef,
    dialogArticleFormRules,
    isVisible,
    closeDialog,
    uploadImage,
    publish,
    submitForm,
    articleTitleVAlidate
  };
}
